﻿using System;
using System.Collections.Generic;
using System.Windows.Threading;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Collections.ObjectModel;

namespace WpfImageDuplicates
{
    /// <summary>
    /// Interaction logic for FullImageView.xaml
    /// </summary>
    public partial class ImageCollectionView : UserControl
    {
        private DispatcherTimer _timer;
        private bool _forceRefresh;
        private double _lastOffset;
        protected List<ThumbnailView> _thumbs = new List<ThumbnailView>();

        public event EventHandler<ObjectEventArgs<FileImageViewModel>> WantView;

        public bool ForceRefresh
        {
            set
            {
                if (value == true)
                {
                    foreach (var thumb in _thumbs)
                    {
                        thumb.Dirty = true;
                    }
                }
                _forceRefresh = value;
            }
        }

        public static readonly DependencyProperty FileImageCollectionViewModelProperty =
            DependencyProperty.Register("FileImageCollectionViewModel", typeof(FileImageCollectionViewModel), typeof(ImageCollectionView), new PropertyMetadata(null, OnFileImageCollectionViewModelPropertyChanged));

        public static readonly DependencyProperty SelectedImagesProperty =
            DependencyProperty.Register("SelectedImages", typeof(List<FileImageViewModel>), typeof(ImageCollectionView), new PropertyMetadata(null, OnSelectedImagesPropertyChanged));

        public List<FileImageViewModel> SelectedImages
        {
            get { return (List<FileImageViewModel>)GetValue(SelectedImagesProperty); }
            set { SetValue(SelectedImagesProperty, value); }
        }

        private static void OnSelectedImagesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ImageCollectionView source = d as ImageCollectionView;
            List<FileImageViewModel> v = e.NewValue as List<FileImageViewModel>;
            source.UpdateSelectedImages(v);
        }

        private void UpdateSelectedImages(List<FileImageViewModel> selected)
        {
            SelectedImages = selected;
            // HEREHERE
            //lstItems.SelectedItems.Clear();

            //foreach (var vm in selected)
            //{
            //    lstItems.SelectedItems.Add(vm);
            //}
        }

        public List<FileImageViewModel> GetSelectedImages()
        {
            SelectedImages = lstItems.GetSelected<FileImageViewModel>();
            return SelectedImages;
        }

        public FileImageCollectionViewModel FileImageCollectionViewModel
        {
            get { return (FileImageCollectionViewModel)GetValue(FileImageCollectionViewModelProperty); }
            set { SetValue(FileImageCollectionViewModelProperty, value); }
        }

        private static void OnFileImageCollectionViewModelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ImageCollectionView source = d as ImageCollectionView;
            FileImageCollectionViewModel vNew = e.NewValue as FileImageCollectionViewModel;
            FileImageCollectionViewModel vOld = e.OldValue as FileImageCollectionViewModel;
            if (vNew != vOld)
            {
                source.UpdateFileImageCollectionViewModel(vNew, vOld);
            }
        }

        private void UpdateFileImageCollectionViewModel(FileImageCollectionViewModel viewModel, FileImageCollectionViewModel viewModelOld)
        {
            if (viewModelOld != null)
            {
                viewModelOld.ThumbnailsInvalidated -= FileImageCollectionViewModel_ThumbnailsInvalidated;
            }

            FileImageCollectionViewModel = viewModel;
            FileImageCollectionViewModel.ThumbnailsInvalidated += new EventHandler(FileImageCollectionViewModel_ThumbnailsInvalidated);

            // Let the UI bind to the view-model.
            this.DataContext = FileImageCollectionViewModel;

            _timer = new DispatcherTimer() { Interval = new TimeSpan(0, 0, 1), IsEnabled = true };
            _timer.Tick += new EventHandler(timer_Tick);
            _timer.Start();
        }

        void FileImageCollectionViewModel_ThumbnailsInvalidated(object sender, EventArgs e)
        {
            ForceRefresh = true;
        }

        public List<ThumbnailView> GetAllThumbnailViews()
        {
            return _thumbs;
        }

        void timer_Tick(object sender, EventArgs e)
        {
            var sv = lstItems.GetAllChildren<ScrollViewer>(true);
            double lastOffset = 0D;

            if (sv.Count > 0)
            {
                lastOffset = sv[0].VerticalOffset;
            }

            _timer.Stop();
            Window1._metaData.SaveIfDirty(Window1._metaDataFilePath);

            if (_lastOffset != lastOffset || _forceRefresh)
            {
                _lastOffset = lastOffset;
                var children = GetAllThumbnailViews();
                bool visOnce = false;
                bool skipVis = false;

                foreach (var item in children)
                {
                    bool vis = false;

                    if (!skipVis)
                    {
                        bool? visible = item.GetIsVisibleInScroller(sv[0]);
                        if (visible == null)
                        {
                            vis = false;
                        }
                        else
                        {
                            vis = visible == true ? true : false;
                        }
                    }

                    if (vis)
                    {
                        visOnce = true;
                    }

                    if (visOnce && !vis)
                    {
                        skipVis = true;
                    }

                    if (!vis && !item.FileImageViewModel.BitmapImageLoaded)
                    {
                        continue;
                    }

                    item.UpdateIfDirty(vis, false);
                }
            }
            _timer.Start();
        }

        public ImageCollectionView()
        {
            InitializeComponent();
        }

        protected void thumbnailView_WantView(object sender, ObjectEventArgs<FileImageViewModel> args)
        {
            if (WantView != null)
                WantView(this, args);
        }

        private void thumbnailView_Loaded(object sender, RoutedEventArgs e)
        {
            var thumb = sender as ThumbnailView;

            if (!_thumbs.Contains(thumb))
                _thumbs.Add(thumb);
        }

        private void lstItems_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                var images = GetSelectedImages();
                FileImageCollectionViewModel.Delete(images);
            }
        }

        private void thumbnailView_Unloaded(object sender, RoutedEventArgs e)
        {
            var thumb = sender as ThumbnailView;
            _thumbs.Remove(thumb);
        }
    }
}
